package j20251101;

public class Demo3 {
    // 核心状态
    private volatile Thread owner = null;
    private volatile int count = 0;
    private final Object mutex = new Object();

    public void lock() {
        Thread current = Thread.currentThread();

        synchronized (mutex) {
            if (owner == null) {
                // 锁未被持有，直接获取
                owner = current;
                count = 1;
            } else if (owner == current) {
                // 重入：当前线程已经持有锁
                count++;
            } else {
                // 其他线程持有锁，等待
                while (owner != null) {
                    try {
                        mutex.wait();
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                        throw new RuntimeException("Interrupted while waiting for lock", e);
                    }
                }
                owner = current;
                count = 1;
            }
        }
    }

    public void unlock() {
        Thread current = Thread.currentThread();

        synchronized (mutex) {
            if (owner != current) {
                throw new IllegalMonitorStateException(
                        "Current thread does not hold the lock");
            }

            count--;
            if (count == 0) {
                owner = null;
                mutex.notifyAll(); // 唤醒等待的线程
            }
        }
    }

    public boolean tryLock() {
        Thread current = Thread.currentThread();

        synchronized (mutex) {
            if (owner == null) {
                owner = current;
                count = 1;
                return true;
            } else if (owner == current) {
                count++;
                return true;
            } else {
                return false;
            }
        }
    }

    public boolean isHeldByCurrentThread() {
        return owner == Thread.currentThread();
    }

    public int getHoldCount() {
        synchronized (mutex) {
            return isHeldByCurrentThread() ? count : 0;
        }
    }
}
